{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1> Deploying and predicting with model </h1>\n",
    "\n",
    "This notebook illustrates:\n",
    "<ol>\n",
    "<li> Deploying model\n",
    "<li> Predicting with model\n",
    "</ol>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!sudo chown -R jupyter:jupyter /home/jupyter/training-data-analyst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ensure the right version of Tensorflow is installed.\n",
    "!pip freeze | grep tensorflow==2.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# change these to try this notebook out\n",
    "BUCKET = 'cloud-training-demos-ml'\n",
    "PROJECT = 'cloud-training-demos'\n",
    "REGION = 'us-central1'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['BUCKET'] = BUCKET\n",
    "os.environ['PROJECT'] = PROJECT\n",
    "os.environ['REGION'] = REGION\n",
    "os.environ['TFVERSION'] = '2.1'  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "if ! gcloud storage ls | grep -q gs://${BUCKET}/; then\n",
    "  gcloud storage buckets create --location ${REGION} gs://${BUCKET}\n",
    "fi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "# copy solution to Lab #5 (skip this step if you still have results from Lab 5 in your bucket)\n",
    "gcloud storage cp --recursive gs://cloud-training-demos/babyweight/trained_model gs://${BUCKET}/babyweight/trained_model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 1\n",
    "\n",
    "What files are present in the model trained directory (gs://${BUCKET}/babyweight/trained_model)?\n",
    "\n",
    "Hint (highlight to see): <p style='color:white'>\n",
    "Run gcloud storage ls in a bash cell.\n",
    "Answer: model checkpoints are in the trained model directory and several exported models (model architecture + weights) are in the export/exporter subdirectory\n",
    "</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Task 2: Deploy trained, exported model </h2>\n",
    "\n",
    "Uncomment and run the the appropriate gcloud lines ONE-BY-ONE to \n",
    "deploy the trained model to act as a REST web service.\n",
    "\n",
    "Hint (highlight to see): <p style='color:white'>\n",
    "The very first time, you need only the last two gcloud calls to create the model and the version.\n",
    "To experiment later, you might need to delete any deployed version, but should not have to recreate the model\n",
    "</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "gcloud storage ls gs://${BUCKET}/babyweight/trained_model/export/exporter/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "MODEL_NAME=\"babyweight\"\n",
    "MODEL_VERSION=\"ml_on_gcp\"\n",
    "MODEL_LOCATION=$(gcloud storage ls gs://${BUCKET}/babyweight/trained_model/export/exporter/ | tail -1)\n",
    "echo \"Deleting and deploying $MODEL_NAME $MODEL_VERSION from $MODEL_LOCATION ... this will take a few minutes\"\n",
    "#gcloud ai-platform versions delete ${MODEL_VERSION} --model ${MODEL_NAME}\n",
    "#gcloud ai-platform models delete ${MODEL_NAME}\n",
    "#gcloud ai-platform models create ${MODEL_NAME} --regions $REGION\n",
    "#gcloud ai-platform versions create ${MODEL_VERSION} --model ${MODEL_NAME} --origin ${MODEL_LOCATION} --runtime-version $TFVERSION"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 3: Write Python code to invoke the deployed model (online prediction)\n",
    "\n",
    "<p>\n",
    "Send a JSON request to the endpoint of the service to make it predict a baby's weight. The order of the responses are the order of the instances.\n",
    "\n",
    "The deployed model requires the input instances to be formatted as follows:\n",
    "<pre>\n",
    "{\n",
    "      'key': 'b1',\n",
    "      'is_male': 'True',\n",
    "      'mother_age': 26.0,\n",
    "      'plurality': 'Single(1)',\n",
    "      'gestation_weeks': 39\n",
    "},\n",
    "</pre>\n",
    "The key is an arbitrary string.  Allowed values for is_male are True, False and Unknown.\n",
    "Allowed values for plurality are Single(1), Twins(2), Triplets(3), Multiple(2+)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from oauth2client.client import GoogleCredentials\n",
    "import requests\n",
    "import json\n",
    "\n",
    "MODEL_NAME = 'babyweight'\n",
    "MODEL_VERSION = 'ml_on_gcp'\n",
    "\n",
    "token = GoogleCredentials.get_application_default().get_access_token().access_token\n",
    "api = 'https://ml.googleapis.com/v1/projects/{}/models/{}/versions/{}:predict' \\\n",
    "         .format(PROJECT, MODEL_NAME, MODEL_VERSION)\n",
    "headers = {'Authorization': 'Bearer ' + token }\n",
    "data = {\n",
    "  'instances': [\n",
    "# TODO: complete\n",
    "    {\n",
    "      'key': 'b1',\n",
    "      'is_male': 'True',\n",
    "      'mother_age': 26.0,\n",
    "      'plurality': 'Single(1)',\n",
    "      'gestation_weeks': 39\n",
    "    },\n",
    "  ]\n",
    "}\n",
    "response = requests.post(api, json=data, headers=headers)\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Task 4: Try out batch prediction </h2>\n",
    "<p>\n",
    "Batch prediction is commonly used when you thousands to millions of predictions.\n",
    "Create a file withe one instance per line and submit using gcloud."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%writefile inputs.json\n",
    "{\"key\": \"b1\", \"is_male\": \"True\", \"mother_age\": 26.0, \"plurality\": \"Single(1)\", \"gestation_weeks\": 39}\n",
    "{\"key\": \"g1\", \"is_male\": \"False\", \"mother_age\": 26.0, \"plurality\": \"Single(1)\", \"gestation_weeks\": 39}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "INPUT=gs://${BUCKET}/babyweight/batchpred/inputs.json\n",
    "OUTPUT=gs://${BUCKET}/babyweight/batchpred/outputs\n",
    "gcloud storage cp inputs.json $INPUT\n",
    "gcloud storage rm --recursive --continue-on-error $OUTPUT \n",
    "gcloud ai-platform jobs submit prediction babypred_$(date -u +%y%m%d_%H%M%S) \\\n",
    "  --data-format=TEXT --region ${REGION} \\\n",
    "  --input-paths=$INPUT \\\n",
    "  --output-path=$OUTPUT \\\n",
    "  --model=babyweight --version=ml_on_gcp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
